package ar.edu.unlam.lyc.notacionIntermedia;

import java.lang.reflect.Method;
import java.util.Stack;

import ar.edu.unlam.lyc.Compilador;

public class PilaOperacional {
	private static Stack<String> instance;

	private PilaOperacional() {
	}

	public static Stack<String> getInstance() {
		if (instance == null) {
			instance = new Stack<String>();
		}
		return instance;
	}

	public static void push(String item) {
		PilaOperacional.getInstance().push(item);
		if (Compilador.DEBUG_MODE) {
			try {
				System.out.println("Push from method "
						+ getCallingMethod().getName() + " : " + item);
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("PilaOperacional: " + instance.toString());
		}
	}

	public static String pop() {
		String item = PilaOperacional.getInstance().pop();
		if (Compilador.DEBUG_MODE) {
			try {
				System.out.println("Pop from method + "
						+ getCallingMethod().getName() + " : " + item);
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("PilaOperacional: " + instance.toString());
		}
		return item;
	}

	private static Method getCallingMethod() throws ClassNotFoundException {
		final Thread t = Thread.currentThread();
		final StackTraceElement[] stackTrace = t.getStackTrace();
		final StackTraceElement ste = stackTrace[3];
		final String methodName = ste.getMethodName();
		final String className = ste.getClassName();
		Class<?> kls = Class.forName(className);
		do {
			for (final Method candidate : kls.getDeclaredMethods()) {
				if (candidate.getName().equals(methodName)) {
					return candidate;
				}
			}
			kls = kls.getSuperclass();
		} while (kls != null);
		return null;
	}
}
